


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

%matplotlib inline
plt.rcParams['font.sans-serif'] = ['SimHei']



#读取数据

df = pd.read_csv('data/kelu.csv')
print(df.info())
df


df['date'] = pd.to_datetime(df['time'],format='%Y/%m/%d')
#df['year-month-first'] = df['date'].values.astype('datetime64[M]')
df['year_month'] = df['date'].dt.to_period('M')
print(df)
print(df.describe())
df.info()


#每日销量分析
gp_date = df.groupby(by='date').count()
print(gp_date)
plt.figure(figsize=(20,4))
gp_date['frequency'].plot()
plt.show()


#每月销量分析
gp_month = df.groupby(by='year_month').count()
print(gp_month)
plt.figure(figsize=(20,4))
gp_month['frequency'].plot()
plt.show()


gp_user = df.groupby(by="author")

gp_user_c = gp_user['frequency'].count().reset_index()
gp_user_c.tail(60)


gp_user_a = gp_user['amount'].sum().reset_index()
gp_user_a.tail(60)


gp_user_m = pd.merge(left=gp_user_c,right=gp_user_a,on="author",how="inner")
gp_user_m.tail(60)


gp_user_m.plot.scatter(x='frequency',y='amount')
plt.show()


#用户购买数量分析
gp_user = df.groupby(by='author')
gp_user_f = gp_user['frequency'].count().reset_index()
print(gp_user_f)
gp_user_f.plot.hist(bins = 50)  #柱子宽度= （max-min）/bins

plt.xlim(1,17)
plt.show()


#购买两次及以上的情况
twice_user = gp_user_f.reset_index(drop=True)
twice_user = twice_user[twice_user['frequency'] > 1]
twice_user


twice_user['frequency'].plot.hist(bins = 50)
plt.title('pucharse times more than 2')
plt.show()


f_user = twice_user.groupby(by='frequency').count()
f_user


#购买用户在2-5次的用户分析
#gp_user_f = gp_user_f[(gp_user_f['frequency']>1) & (gp_user_f['frequency']<6)].reset_index(drop=True) # 方案1
gp_user_1_5 = gp_user_f[gp_user_f["frequency"].between(1, 5, inclusive="both")].reset_index(drop=True)
gp_user_1_5


gp_user_f_values = gp_user_1_5['frequency'].value_counts()
gp_user_f_values


labels = ['1次','2次','3次','4次','5次']

plt.pie(gp_user_f_values,labels=labels,autopct='%1.1f%%')
plt.title('purchase times between 1 and 5')
plt.legend()
plt.show()


#购买用户在2-5次的用户分析
gp_user_2_5 = gp_user_f[gp_user_f["frequency"].between(2, 5, inclusive="both")].reset_index(drop=True)
gp_user_2_5


gp_user_f_values = gp_user_2_5['frequency'].value_counts()
gp_user_f_values


labels = ['2次','3次','4次','5次']

plt.pie(gp_user_f_values,labels=labels,autopct='%1.1f%%')
plt.title('purchase times between 2 and 5')
plt.legend()
plt.show()


#复购率分析  在某一时间窗口内（多指一个月）消费此处在两次及以上用户在总消费用户的占比
print(df.head())
pivot_user = df.pivot_table(index="author",values="frequency",columns="year_month",aggfunc="count" ).fillna(0)
pivot_user


pivot_user_re =pivot_user.map(lambda x: 1 if x>1 else 0 if x == 1 else np.nan)
pivot_user_re


pivot_user_re.sum()


(pivot_user_re.sum()/pivot_user_re.count()).plot()
plt.xlabel("时间")
plt.xlabel("复购率")
plt.title('用户复购率')
plt.show()


pivot_user_re.sum().plot()
plt.xlabel("时间")
plt.xlabel("复购人数")
plt.title('每月用户复购人数折线图')
plt.show()


#回购率分析

def judge_back(data):
    status = []
    status.append(0 if data.iloc[0] >0 else np.nan)
    for i in range(len(data) -1):
        if data.iloc[i+1] >= 1:
            if data.iloc[i] >= 1:
                status.append(1)
            else:
                status.append(0)
        else:
            status.append(np.nan)
    return pd.Series(status,pivot_user.columns)

pivot_user_back = pivot_user.apply(lambda x:judge_back(x),axis=1)
pivot_user_back



pivot_user_back.sum()


(pivot_user_back.sum()/pivot_user_back.count()).plot()
plt.xlabel('month')
plt.ylabel('back purchase rate')
plt.show()


#回购人数分析

(pivot_user_back.sum()).plot()
plt.xlabel('month')
plt.ylabel('back purchase number')
plt.show()


#用户分层分析 
def judge_type(data):
    status = []
    for i in range(len(data)):  
        if i == 0:
            if data.iloc[i] >= 1:
                status.append('new')
            else:
                status.append('noreg')
        else:
            if data.iloc[i] >= 1:
                if data.iloc[i-1] >=1:
                    status.append('active')
                else:
                    if status[i-1] == 'noreg':
                        status.append('new')
                    else: 
                        status.append('return')
            else:
                if status[i-1] == 'noreg':
                    status.append('noreg')
                else: 
                    status.append('inactive')
            
    return pd.Series(status,pivot_user.columns)
    
type_table = pivot_user.apply(lambda x:judge_type(x),axis=1)
print(type_table)
type_res = type_table.replace('noreg',np.nan).apply(lambda x:x.value_counts())
type_res



type_res.T.plot.area(stacked=False)
plt.show()


#每月不同用户占比

type_rate = type_res.apply(lambda x:x /x.sum())
type_rate


type_rate.T.plot()

plt.show()


#每月活跃用户占比

type_rate.loc['active'].plot()
plt.title('active user rate')
plt.show()



#每月回流用户占比

type_rate.loc['return'].plot()
plt.title('return user rate')
plt.show()



np.mean(type_rate.loc['return'])


#用户生命周期分析 每一个用户最后一次购买商品的时间和第一次购买的时间差

user_period = df.groupby("author")['date'].apply(lambda x: x.max() - x.min())/np.timedelta64(1,'D')
user_period = user_period.reset_index()
print(user_period)
user_period.describe()




print(user_period['date'])

#各个日期出现的次数
life_time = user_period['date'].value_counts().sort_values(ascending=False)
print(life_time.head(30))

#绘制直方图 
user_period['date'].plot.hist(bins=100,figsize=(12,6))

#plt.ylim(0,1000) 
plt.tight_layout()
plt.show()



#生命周期大于0的用户直方图
#绘制直方图 
user_period[user_period['date'] >0]['date'].plot.hist(bins=100,figsize=(12,6))

plt.tight_layout()
plt.show()

print(user_period[user_period['date'] >0]['date'].mean())


#用户留存率 1-90天 留存用户与总用户的占比
#使用pd.cut函数
#计算方式，每次消费时间

user_contain = gp_user['date'].apply(lambda x: x-x.min()).reset_index()[['author','date']]
user_contain['date_diff'] = user_contain['date']/np.timedelta64(1,'D')
print(user_contain[user_contain['author'].str.contains('Cri')]) #验证
user_contain




#生成时间跨度，判断属于哪个区间

bin = [ i *90  for i in range(11) ]
bin



user_contain['date_diff_range'] = pd.cut(user_contain['date_diff'],bins=bin)  #  参数 include_lowest=True 第一个区间是否左闭合 
user_contain.tail(60)


# 统计每个游客，在不同时间段内的消费频率和
user_contain['frequecy'] = 1
print(user_contain)
gp_retention = user_contain.groupby(by=['author','date_diff_range'],observed=False)['frequecy'].sum().unstack()
gp_retention


# 判断是否留存用户

gp_retention = gp_retention.map(lambda x: 1 if x>=1 else 0)
gp_retention.head(60)


retention_rate = gp_retention.sum() / gp_retention.count()
retention_rate



plt.figure(figsize=(18,6))
plt.subplot(121)
retention_rate.plot()

plt.subplot(122)
retention_rate.plot.bar()

plt.tight_layout()
plt.show()



